local ROT = require 'rot'
local Color = require 'game.color'
local UI = require 'game.ui'

local state = ROT.Class:extend()

local Effect = require 'game.proto.effect'

local function noop() end

function state:init(game, play, opt)
    self.game = game
    self.play = play
    self.offsetX, self.offsetY = 0, 0

    self.title = opt and opt.title or 'Examining surroundings'
    self.mode = opt and opt.mode or 'look'
    self.finish = opt and opt.finish or noop
    self.range = opt and opt.range or 8
end

function state:update()
    local game = self.game
    local play = self.play
    local player = game.player
    local display = game.display
    local radX = 16 + 1
    local radY = math.floor((game.display:getHeight() - 8) * 0.5) + 2
    local x, y = player.x + self.offsetX, player.y + self.offsetY
    local tile, mob, feature, items

    game.display:clear()
    play:drawPlayfield()

    if game.scene.seen:getCell(x, y) then
        tile = game.scene:getTile(
            player.x + self.offsetX, player.y + self.offsetY)
        feature = game.scene:getFeature(
            player.x + self.offsetX, player.y + self.offsetY)
        items = game.scene.stack:getCell(
            player.x + self.offsetX, player.y + self.offsetY)
    end

    if game.scene.field:getCell(x, y) then
        mob = game.scene:getMob(
            player.x + self.offsetX, player.y + self.offsetY)
    else
        tile = feature
    end

    if self.mode == 'target' then
        local path = require 'game.type.line' (x, y, function(x, y)
            local feature = game.scene:getFeature(x, y)
            return game.scene.field:getCell(x, y)
                and not feature.obscure
                -- and not feature.obstruct
        end)
        path:compute(player.x, player.y, function(x, y)
            if x == player.x and y == player.y then return end
            display:write('*', radX + x - player.x, radY + y - player.y, Color.bright)
        end)
    end

    display:write(tile and tile.glyph or ' ',
        radX + self.offsetX, radY + self.offsetY,
        Color.black, tile and tile.color or Color.bright)

    local x1 = 35
    local x2 = 45
    local x3 = 55
    local y = 1

    display:write(self.title, x1, y, Color.brightYellow)

    if not tile then
        y = y + 2
        display:write('Unexplored', x1, y, Color.dark)
    end

    if feature and feature.name then
        y = y + 2
        display:write('Terrain:', x1, y, Color.dark)
        UI.listTiles({feature}, display, x2, y)

        if feature.effect then
            local e = Effect[feature.effect]
            if e.info then
                y = y + 1
                display:write(e.info, x1, y, Color.dark)
            end
        end
    end

    if mob then
        y = y + 2
        display:write('Creature:', x1, y, Color.dark)
        UI.listTiles({mob}, display, x2, y)
    end

    if items then
        y = y + 2
        display:write('Items:', x1, y, Color.dark)
        UI.listTiles(items, display, x2, y)
    end


end

function state:keypressed(key)
    local game = self.game
    local newPos

    if     key==game.keys.move_nw then newPos={ -1, -1 }
    elseif key==game.keys.move_n then newPos={ 0, -1 }
    elseif key==game.keys.move_ne then newPos={ 1, -1 }
    elseif key==game.keys.move_w then newPos={ -1, 0 }
    elseif key==game.keys.rest then game.state = self.play
    elseif key==game.keys.move_e then newPos={ 1, 0 }
    elseif key==game.keys.move_sw then newPos={ -1, 1 }
    elseif key==game.keys.move_s then newPos={ 0, 1 }
    elseif key==game.keys.move_se then newPos={ 1, 1 }
    elseif key==game.keys.examine then game.state = self.play
    elseif key=='\n' then
        game.state = self.play
        self:finish(game.scene:getMob(
            game.player.x + self.offsetX, game.player.y + self.offsetY))
    elseif key=='\27' then game.state = self.play
    end

    if newPos then
        self.offsetX = math.max(-self.range, math.min(self.range, self.offsetX + newPos[1]))
        self.offsetY = math.max(-self.range, math.min(self.range, self.offsetY + newPos[2]))
    end
end

return state
